home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume7 / my_wgetstr < prev    next >
Encoding:
Text File  |  1989-06-03  |  11.6 KB  |  445 lines

  1. Newsgroups: comp.sources.misc
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Subject: v07i015: my_wgetstr(); wgetstr() with line editing
  4. Reply-To: mott@ucscb.UCSC.EDU (Hung H. Le)
  5.  
  6. Posting-number: Volume 7, Issue 15
  7. Submitted-by: mott@ucscb.UCSC.EDU (Hung H. Le)
  8. Archive-name: my_wgetstr
  9.  
  10.     my_wgetstr() is equipvalent to wgetstr() in "curses" but
  11. with line editing feature. Will recognize erase, kill and 
  12. control-w as editing characters.
  13. ------------------------------------------------------------
  14. Hung H. Le
  15. mott@ucscb.ucsc.edu           ...!ucbvax!ucscc!ucscb!mott
  16. mott@ucscd.BITNET            #include <std_disclaimer>
  17. ------------------------------------------------------------
  18.  
  19. --- Include shar file --
  20. #! /bin/sh
  21. # This is a shell archive, meaning:
  22. # 1. Remove everything above the #! /bin/sh line.
  23. # 2. Save the resulting text in a file.
  24. # 3. Execute the file with /bin/sh (not csh) to create the files:
  25. #    README
  26. #    example.c
  27. #    makefile
  28. #    my_wgetstr.c
  29. #    my_wgetstr.h
  30. # This archive created: Sun May 21 10:46:51 1989
  31. # By:    Hung H. Le (Uncle Charlie Summer Camp)
  32. export PATH; PATH=/bin:$PATH
  33. echo shar: extracting "'README'" '(1427 characters)'
  34. if test -f 'README'
  35. then
  36.     echo shar: will not over-write existing file "'README'"
  37. else
  38. sed 's/^    X//' << \SHAR_EOF > 'README'
  39.     X
  40.     X    I wrote my_wgetstr() as a replacement for wgets() in curses.
  41.     X
  42.     XWhat my_getstr() does that wgets() does not?
  43.     X    . line editing as in csh. Erase char, kill char, control-w
  44.     X    are recognized.
  45.     X    . check for overflow. Two possible actions can be taken
  46.     X        1. returns immediately
  47.     X        2. bell() to let user know that buffer is full
  48.     X            only newline and editing chars are passed through at
  49.     X            this point
  50.     X
  51.     XWhat my_getstr() does not do that wgets() does?
  52.     X    . does not check for illegal scrolling.
  53.     X
  54.     XHeader file:
  55.     X    remember to include "my_wgetstr.h"
  56.     X    my_getstr(), RET and NO_RET are defined in there.
  57.     X
  58.     XUsage:
  59.     X    n = my_wgetstr(WINDOW *win, char *str, int size, int ret);
  60.     X    win: the concerned window 
  61.     X    str: storage for input chars
  62.     X    size: my_wgetstr() will get at most (size - 1) chars.
  63.     X    ret: what to do when buffer is full
  64.     X        0: bell()
  65.     X        1: returns
  66.     X    you can use NO_RET or RET
  67.     X    n: number of characters actually gets
  68.     X
  69.     X    my_getstr(char *str, int size, int ret);
  70.     X    is a macro defined as
  71.     X#define my_getstr(str, size) my_wgetstr(stdscr, str, size)
  72.     X    in "my_wgetstr.h"
  73.     X
  74.     Xmy_wgetstr() returns if 
  75.     X    . input is a newline
  76.     X    . if ( (strlen(str) == (size - 1)) and (ret) )
  77.     X
  78.     Xmy_wgetstr() DOES NOT check for illegal scrolling so it is the
  79.     Xprogrammer's job to take care of that.
  80.     X
  81.     XAfter unpack this package. Type "make" to make "example".
  82.     XTry out "example".
  83.     X
  84.     Xwritten by Hung Le 
  85.     Xmott@ucscb.ucsc.edu
  86.     X...!ucbvax!ucscc!ucscb!mott
  87.     X
  88.     X          This code is placed in Public Domain.
  89.     X
  90. SHAR_EOF
  91. if test 1427 -ne "`wc -c < 'README'`"
  92. then
  93.     echo shar: error transmitting "'README'" '(should have been 1427 characters)'
  94. fi
  95. fi # end of overwriting check
  96. echo shar: extracting "'example.c'" '(2271 characters)'
  97. if test -f 'example.c'
  98. then
  99.     echo shar: will not over-write existing file "'example.c'"
  100. else
  101. sed 's/^    X//' << \SHAR_EOF > 'example.c'
  102.     X/*
  103.     X * Example program --
  104.     X * A possible replacement for curses' wgetstr(). Allows
  105.     X * limited editing. Recognizes the erase and kill chars.
  106.     X *
  107.     X * By Hung Le (mott@ucscb.ucsc.edu  ...!ucbvax!ucscc!ucscb!mott)
  108.     X * History:
  109.     X *    01/18/89 - Initial version 
  110.     X *    03/20/89 - add control-w to delete word
  111.     X *
  112.     X * Release to Public Domain 
  113.     X */
  114.     X
  115.     X#include <curses.h>
  116.     X#include <signal.h>
  117.     X/* REMEMBER to include "my_wgetstr.h" */
  118.     X#include "my_wgetstr.h"
  119.     X
  120.     X/* test my_wgetstr() */
  121.     Xmain()
  122.     X{
  123.     X    char buffer[30];
  124.     X    static char *header[] =
  125.     X    {
  126.     X     "INPUT WINDOW",
  127.     X     "Look Ma ... Line editing in curses",
  128.     X     "Erase char to erase, Kill char to delete the whole line",
  129.     X     "control-w to delete a word, empty input line to quit",
  130.     X    };
  131.     X    char ender[81], *name, *getlogin(), *getenv();
  132.     X    int clean_up(), n;
  133.     X    int x_pos, y_pos;
  134.     X    WINDOW *inwin;
  135.     X
  136.     X    initscr();
  137.     X    clear();
  138.     X    refresh();
  139.     X
  140.     X    /* set up interupt handler */
  141.     X    signal(SIGINT, clean_up);
  142.     X
  143.     X    /* set up input window */
  144.     X    inwin = newwin(8, COLS, 3, 0);
  145.     X    if (inwin == (WINDOW *) NULL)
  146.     X        clean_up();
  147.     X
  148.     X    /* print out header */
  149.     X    box(inwin, '|', '-');
  150.     X    for (n = 0; n < 4; n++)
  151.     X        mvwaddstr(inwin, n + 1, COLS / 2 - strlen(header[n]) / 2, header[n]);
  152.     X    mvwaddstr(inwin, 6, 15, "Enter input --> ");
  153.     X    /* get the prompt positions so we can return at later time */
  154.     X    getyx(inwin, y_pos, x_pos);
  155.     X    wrefresh(inwin);
  156.     X
  157.     X    /* now get string */
  158.     X    do
  159.     X    {
  160.     X        /* clear last input */
  161.     X        wmove(inwin, y_pos, x_pos);
  162.     X        wclrtoeol(inwin);
  163.     X        box(inwin, '|', '-');
  164.     X        wrefresh(inwin);
  165.     X
  166.     X        /*
  167.     X         * get string. NO_RET=0 and RET=1 are defined in
  168.     X         * "my_wgetstr.h" 
  169.     X         */
  170.     X        n = my_wgetstr(inwin, buffer, sizeof(buffer), NO_RET);
  171.     X
  172.     X        /* print out the result of my_wgetstr */
  173.     X        move(15, 15);
  174.     X        clrtoeol();
  175.     X        mvprintw(15, 15, "Received %d chars -- \"%s\"", n, buffer);
  176.     X        refresh();
  177.     X
  178.     X        /* move back to the input prompt */
  179.     X        wmove(inwin, y_pos, x_pos);
  180.     X        wrefresh(inwin);
  181.     X    }
  182.     X    while (n != 0);        /* while input is not empty */
  183.     X
  184.     X    name = getenv("NAME");
  185.     X    if (name == (char *) NULL)    /* use login if NAME is not set */
  186.     X        name = getlogin();
  187.     X    /* say good bye */
  188.     X    move(15, 15);
  189.     X    clrtoeol();
  190.     X    sprintf(ender, "GOOD BYE, \"%s\"", name);
  191.     X    mvprintw(15, COLS / 2 - strlen(ender) / 2, "%s", ender);
  192.     X
  193.     X    /* move to last line ... looks cleaner this way */
  194.     X    move(LINES - 1, 0);
  195.     X    refresh();
  196.     X    clean_up();
  197.     X}
  198.     X
  199.     Xclean_up()
  200.     X{
  201.     X    endwin();
  202.     X    exit();
  203.     X}
  204. SHAR_EOF
  205. if test 2271 -ne "`wc -c < 'example.c'`"
  206. then
  207.     echo shar: error transmitting "'example.c'" '(should have been 2271 characters)'
  208. fi
  209. fi # end of overwriting check
  210. echo shar: extracting "'makefile'" '(128 characters)'
  211. if test -f 'makefile'
  212. then
  213.     echo shar: will not over-write existing file "'makefile'"
  214. else
  215. sed 's/^    X//' << \SHAR_EOF > 'makefile'
  216.     XLIBS= -lcurses -ltermcap
  217.     XOBJS= example.o my_wgetstr.o
  218.     XCFLAGS= -s -O
  219.     X
  220.     Xexample: $(OBJS)
  221.     X    cc $(CFLAGS) -o example $(OBJS) $(LIBS) 
  222. SHAR_EOF
  223. if test 128 -ne "`wc -c < 'makefile'`"
  224. then
  225.     echo shar: error transmitting "'makefile'" '(should have been 128 characters)'
  226. fi
  227. fi # end of overwriting check
  228. echo shar: extracting "'my_wgetstr.c'" '(3993 characters)'
  229. if test -f 'my_wgetstr.c'
  230. then
  231.     echo shar: will not over-write existing file "'my_wgetstr.c'"
  232. else
  233. sed 's/^    X//' << \SHAR_EOF > 'my_wgetstr.c'
  234.     X/*
  235.     X * A possible replacement for curses' wgetstr(). Allows
  236.     X * line editing as in csh. 
  237.     X * Recognizes the erase, kill chars, word deleting.
  238.     X *
  239.     X * By Hung Le (mott@ucscb.ucsc.edu  ...!ucbvax!ucscc!ucscb!mott)
  240.     X * History:
  241.     X *    01/18/89 - Initial version 
  242.     X *    03/20/89 - Add control-w to delete word
  243.     X *  05/17/89 - add option to return immediately or to bell()
  244.     X *            when buffer is full.
  245.     X *
  246.     X * Release to Public Domain 
  247.     X */
  248.     X#include <curses.h>
  249.     X#include <sys/ioctl.h>
  250.     X#include <sgtty.h>
  251.     X
  252.     X#define STD_INPUT 0        /* standard input */
  253.     X#define NEWLINE '\n'
  254.     X#define SPACE ' '
  255.     X/* default for erase and kill characters */
  256.     X#define ERASE '\010'
  257.     X#define KILL '\025'
  258.     X#define WORD '\027'
  259.     X
  260.     X/* You bugger !!! you did something wrong */
  261.     X#define bell() fprintf(stderr,"%c", '\007')
  262.     X
  263.     X/*
  264.     X * my_wgetstr(WINDOW *win, char *str, int size, int ret)
  265.     X *    win: the concerned window
  266.     X *     str: buffer holding input
  267.     X *    size: (size -1) is the maximum chars to get
  268.     X *    ret: flag indicating what to do when (size -1) is reached
  269.     X *        0: ring bell()
  270.     X *        1: returns
  271.     X *        two macros are defined in "my_wgetstr.h" as RET=1 and NO_RET=0
  272.     X *
  273.     X * works same as wgetstr() in curses but allows editing.
  274.     X * Recognizes the erase character and the kill character and
  275.     X * WORD as the word deleting char.
  276.     X * Will try to get the erase and kill char from the terminal setting.
  277.     X * If failed, will use the default ERASE and KILL definitions.
  278.     X * Word char is set to WORD.
  279.     X *
  280.     X * DOES NOT check for illegal scrolling.
  281.     X * Returns
  282.     X *    . when received a new line character 
  283.     X *    . if ( (strlen(str) == (size - 1)) and (ret) )        
  284.     X *
  285.     X * str[size - 1] must be set to '\0' to end the string properly 
  286.     X * so my_wgetstr(errwin, str, 8) will get at most 7 characters.
  287.     X *
  288.     X * Returned value is the number of chars read. 
  289.     X */
  290.     X
  291.     Xmy_wgetstr(win, str, size, ret)
  292.     XWINDOW *win;
  293.     Xchar *str;
  294.     Xint size;
  295.     Xint ret;
  296.     X{
  297.     X    struct sgttyb ttyb;
  298.     X    char erase_char, kill_char;
  299.     X    register int x_pos, y_pos, index, in;
  300.     X
  301.     X    if (ioctl(STD_INPUT, TIOCGETP, &ttyb) == -1)
  302.     X    {
  303.     X        /*
  304.     X         * failed to get terminal setting. Let's use the default
  305.     X         * ERASE and KILL 
  306.     X         */
  307.     X        erase_char = ERASE;
  308.     X        kill_char = KILL;
  309.     X    }
  310.     X    else
  311.     X    {
  312.     X        erase_char = ttyb.sg_erase;
  313.     X        kill_char = ttyb.sg_kill;
  314.     X    }
  315.     X
  316.     X    /*
  317.     X     * since we are going to set noecho() and crmode() let's be safe and
  318.     X     * save the current tty 
  319.     X     */
  320.     X    savetty();
  321.     X    noecho();
  322.     X    crmode();
  323.     X
  324.     X    /* get current position */
  325.     X    getyx(win, y_pos, x_pos);
  326.     X    /* intializing */
  327.     X    index = 0;
  328.     X    str[index] = '\0';
  329.     X
  330.     X    /* while input char is not NEWLINE */
  331.     X    while ((in = getch() & 0177) != NEWLINE)
  332.     X    {
  333.     X        /* if buffer is full (size -1) */
  334.     X        if (index >= size - 1)
  335.     X            if (ret)/* return flag set, return immediately */
  336.     X                break;
  337.     X            else    /* allows editing chars to pass through */
  338.     X            if ((in != erase_char) && (in != kill_char) && (in != WORD))
  339.     X            {
  340.     X                /* warns user that buffer is full */
  341.     X                bell();
  342.     X                continue;
  343.     X            }
  344.     X
  345.     X        if (in == erase_char)    /* ERASING */
  346.     X        {
  347.     X            if (index > 0)
  348.     X            {
  349.     X                mvwaddch(win, y_pos, --x_pos, SPACE);
  350.     X                str[--index] = SPACE;
  351.     X                wmove(win, y_pos, x_pos);
  352.     X            }
  353.     X            else
  354.     X                bell();
  355.     X        }
  356.     X        else
  357.     X        if (in == kill_char)    /* KILLING */
  358.     X        {
  359.     X            if (index > 0)
  360.     X                while (index > 0)
  361.     X                {
  362.     X                    mvwaddch(win, y_pos, --x_pos, SPACE);
  363.     X                    str[--index] = SPACE;
  364.     X                    wmove(win, y_pos, x_pos);
  365.     X                }
  366.     X            else
  367.     X                bell();
  368.     X        }
  369.     X        else
  370.     X        if (in == WORD)    /* WORD DELETING */
  371.     X        {
  372.     X            if (index > 0)
  373.     X            {
  374.     X                /* throw away all spaces */
  375.     X                while ((index > 0) && (str[index - 1] == SPACE))
  376.     X                {
  377.     X                    mvwaddch(win, y_pos, --x_pos, SPACE);
  378.     X                    str[--index] = SPACE;
  379.     X                    wmove(win, y_pos, x_pos);
  380.     X                }
  381.     X                /* move back until see another space */
  382.     X                while ((index > 0) && (str[index - 1] != SPACE))
  383.     X                {
  384.     X                    mvwaddch(win, y_pos, --x_pos, SPACE);
  385.     X                    str[--index] = SPACE;
  386.     X                    wmove(win, y_pos, x_pos);
  387.     X                }
  388.     X            }
  389.     X            else
  390.     X                bell();
  391.     X        }
  392.     X        else
  393.     X        {
  394.     X            mvwaddch(win, y_pos, x_pos++, in);
  395.     X            str[index++] = in;
  396.     X        }
  397.     X        /* show result */
  398.     X        wrefresh(win);
  399.     X    }
  400.     X    /* ends the string properly */
  401.     X    str[index] = '\0';
  402.     X    /* restore the tty */
  403.     X    resetty();
  404.     X    /* returns number of chars read */
  405.     X    return (index);
  406.     X}
  407. SHAR_EOF
  408. if test 3993 -ne "`wc -c < 'my_wgetstr.c'`"
  409. then
  410.     echo shar: error transmitting "'my_wgetstr.c'" '(should have been 3993 characters)'
  411. fi
  412. fi # end of overwriting check
  413. echo shar: extracting "'my_wgetstr.h'" '(400 characters)'
  414. if test -f 'my_wgetstr.h'
  415. then
  416.     echo shar: will not over-write existing file "'my_wgetstr.h'"
  417. else
  418. sed 's/^    X//' << \SHAR_EOF > 'my_wgetstr.h'
  419.     X/*
  420.     X * A possible replacement for curses' wgetstr(). Allows
  421.     X * limited editing. Recognizes the erase and kill chars.
  422.     X *
  423.     X * By Hung Le (mott@ucscb.ucsc.edu  ...!ucbvax!ucscc!ucscb!mott)
  424.     X * History:
  425.     X *    05/18/89 - Initial version 
  426.     X *
  427.     X * Release to Public Domain 
  428.     X */
  429.     X
  430.     X/* following the curses's convention */
  431.     X#define my_getstr(str,size,ret) my_wgetstr(stdscr,str,size,ret)
  432.     X#define RET 1
  433.     X#define NO_RET 0
  434.     X
  435. SHAR_EOF
  436. if test 400 -ne "`wc -c < 'my_wgetstr.h'`"
  437. then
  438.     echo shar: error transmitting "'my_wgetstr.h'" '(should have been 400 characters)'
  439. fi
  440. fi # end of overwriting check
  441. #    End of shell archive
  442. exit 0
  443.  
  444.  
  445.